import { useState, useEffect, FC, useRef, RefObject } from 'react'
import Model from './components/modal'
import ListItem from './components/ListItem'
import style from './index.module.less'
import { Button, Input, message, List, Space, Select } from 'antd'
import FreeScroll from 'react-free-scrollbar'
import { PDFTemplateSchema } from '@components/schema/pdf'
import { FileSchema } from '@src/components/schema/fileSchema'
import { getTemplateFileRequest, delRequest, getTemplateListRequest } from './ajax'
import { awaitWrap } from '@src/assets/js/tool'
import { useDispatch } from 'react-redux'
import { addScrollEvent, delScrollEvent } from '@src/redux/actions/globalEvent'
import { confirmAction } from '@js/tool'
import { Document, Page } from 'react-pdf'
import { LoadingOutlined } from '@ant-design/icons'
import Dictionary from '@js/dictionary'

const { Option } = Select

const FreeScrollBar = FreeScroll as unknown as FC<any>

function renderItem (d: PDFTemplateSchema, currentTemplateid: string, selectHandle: (id: string) => void) {
  return <ListItem active={d.id === currentTemplateid} data={d} selectHandle={id => selectHandle(id)} />
}

async function getTemplateById (id: string, setFIle: (v: FileSchema) => void) {
  const [e, d] = await awaitWrap(getTemplateFileRequest(id))
  if (e === null && d !== null) {
    setFIle(d)
  }
}

function fixHandle (setFixedMenuStyle: (v: {[k: string]: any}) => void) {
  const t = window.document.documentElement.scrollTop
    if (t > 80) {
      setFixedMenuStyle({ position: 'fixed', top: 80, left: '232px' })
    } else {
      setFixedMenuStyle({})
    }
}

function renderBtns (
  currentTemplateid: string,
  templateIdMap: { [k: string]: PDFTemplateSchema },
  setJustyModifyFile: (v: boolean) => void,
  setModifyTemplate: (v: PDFTemplateSchema | null) => void,
  setVisible: (v: boolean) => void,
  setCurrentTemplateid: (v: string) => void,
  setFile: (v: FileSchema | null) => void,
  refreshFn: () => void
) {
  const template = currentTemplateid ? templateIdMap[currentTemplateid] : { user_define: undefined }
  if (!currentTemplateid) {
    return null
  }
  if (template) {
    return (
      <>
        <Button type='primary' onClick={() => modifyHandle(false, currentTemplateid, templateIdMap, setJustyModifyFile, setModifyTemplate, setVisible)}>修改文书</Button>
        <Button type='primary' ghost onClick={() => modifyHandle(true, currentTemplateid, templateIdMap, setJustyModifyFile, setModifyTemplate, setVisible)}>更换模版文件</Button>
        <Button onClick={() => delHandle(currentTemplateid, templateIdMap, setCurrentTemplateid, setFile, refreshFn)}>删除文书</Button>
      </>
    )
  }
  return <Button type='primary' ghost onClick={() => modifyHandle(true, currentTemplateid, templateIdMap, setJustyModifyFile, setModifyTemplate, setVisible)}>更换模版文件</Button>
}

function modifyHandle (
  justyModifyFile: boolean,
  currentTemplateid: string,
  templateIdMap: { [k: string]: PDFTemplateSchema },
  setJustyModifyFile: (v: boolean) => void,
  setModifyTemplate: (v: PDFTemplateSchema | null) => void,
  setVisible: (v: boolean) => void
) {
  const template = templateIdMap[currentTemplateid]
  if (!template) {
    return message.warning('文书模板不存在')
  }
  setVisible(true)
  setJustyModifyFile(justyModifyFile)
  setModifyTemplate(template)
}

// 删除按钮回调
function delHandle (
  currentTemplateid: string,
  templateIdMap: { [k: string]: PDFTemplateSchema },
  setCurrentTemplateid: (v: string) => void,
  setFile: (v: FileSchema | null) => void,
  refreshFn: () => void
) {
  const template = templateIdMap[currentTemplateid]
  if (!template) {
    return message.warning('文书模板不存在')
  }
  confirmAction(`您确定要删除 ${template.title} 吗？`, async () => {
    const hide = message.loading('删除文书模板中', 120)
    const [e] = await awaitWrap(delRequest(currentTemplateid))
    hide()
    if (e === null) {
      setCurrentTemplateid('')
      setFile(null)
      setTimeout(() => {
        refreshFn()
      }, 100)
    }
  })
}

function renderPdf (
  ready: boolean,
  numPages: number,
  file: FileSchema | null,
  width: number,
  height: number,
  docBoxRef: RefObject<HTMLDivElement>,
  setNumPages: (v: number) => void,
  setReady: (v: boolean) => void,
  setWidth: (v: number) => void,
  setHeight: (v: number) => void
) {
  if (!file) {
    return null
  }
  if (!file.pdf_path) {
    return <span>文书生成中</span>
  }
  return (
    <Document
      loading={(
        <div className={style['empty-page']} style={{ width: width ? `${width}px` : '100%', height: `${height || 100}px`  }}>
          <div>
            <LoadingOutlined className={style['loading-icon']} />
            <div className={style['loading-text']}>加载中</div>
          </div>
        </div>
      )}
      error='文书生成失败。'
      file={`${file.pdf_path}`}
      onLoadSuccess={(e: { numPages: number }) => {
        const width = docBoxRef.current?.offsetWidth || 0
        setReady(true)
        setNumPages(e.numPages)
        setWidth(width)
        setHeight(width * 1.4140625)
      }}
      options={{ cMapUrl: 'cmaps/', cMapPacked: true }}
    >
      {renderPages(ready, numPages, width, height)}
    </Document>
  )
}

// 渲染pdf页面
function renderPages (ready: boolean, numPages: number, width: number, height: number) {
  if (ready) {
    const arr = []
    for (let i = 0; i < numPages; i++) {
      arr.push((
        <div className={style.page} key={i}>
          <Page pageNumber={i + 1} width={width} height={height} renderTextLayer={false} renderAnnotationLayer={false} />
        </div>
      ))
    }
    return arr
  }
}

const fnObj = {
  refreshFn: () => {}
}

async function getTemplateList (
  searchText: string,
  tempSignType: string,
  currentTemplateid: string,
  setLoading: (v: boolean) => void,
  setTemplateList: (v: PDFTemplateSchema[]) => void,
  setTemplateIdMap: (v: { [k: string]: PDFTemplateSchema }) => void,
  setFilterTemplateList: (v: PDFTemplateSchema[]) => void,
  setCurrentTemplateid: (v: string) => void,
  setFile: (v: FileSchema | null) => void
): Promise<void> {
  setLoading(true)
  const [e, l] = await awaitWrap(getTemplateListRequest())
  setLoading(false)
  if (e === null && l !== null) {
    const map: { [k: string]: PDFTemplateSchema } = {}
    l.forEach(i => {
      map[i.id] = i
    })
    const filterTemplateList = l.filter(li => {
      if (searchText) {
        return li.title.indexOf(searchText) !== -1 && li.temp_sign_type === tempSignType
      }
      return li.temp_sign_type === tempSignType
    })
    const id = currentTemplateid || (filterTemplateList.length ? filterTemplateList[0].id : '')
    setTemplateList(l)
    setTemplateIdMap(map)
    setFilterTemplateList(filterTemplateList)
    setCurrentTemplateid(id)
    setFile(null)
    if (id !== '') {
      getTemplateById(id, setFile)
    }
  }
}

interface Props {
  title: string
}

function Main ({ title }: Props) {
  const docBoxRef = useRef<HTMLDivElement>(null)
  const [visible, setVisible] = useState(false)
  const [modifyTemplate, setModifyTemplate] = useState<PDFTemplateSchema | null>(null)
  const [justyModifyFile, setJustyModifyFile] = useState(false)
  const [loadingList, setLoadingList] = useState(false)
  const [templateList, setTemplateList] = useState<PDFTemplateSchema[]>([])
  const [filterTemplateList, setFilterTemplateList] = useState<PDFTemplateSchema[]>([])
  const [currentTemplateid, setCurrentTemplateid] = useState('')
  const [file, setFile] = useState<FileSchema | null>(null)
  const [searchText, setSearchText] = useState('')
  const [tempSignType, setTempSignType] = useState('location')
  const [fixedMenuStyle, setFixedMenuStyle] = useState<{ [k: string]: any }>({})
  const [templateIdMap, setTemplateIdMap] = useState<{ [k: string]: PDFTemplateSchema }>({})
  const [ready, setReady] = useState(false)
  const [numPages, setNumPages] = useState(1)
  const [width, setWidth] = useState(0)
  const [height, setHeight] = useState(0)
  const dispatch = useDispatch()
  useEffect(() => {
    fnObj.refreshFn = () => getTemplateList(searchText, tempSignType, currentTemplateid, setLoadingList, setTemplateList, setTemplateIdMap, setFilterTemplateList, setCurrentTemplateid, setFile)
  }, [searchText, tempSignType, currentTemplateid])
  useEffect(() => {
    fnObj.refreshFn()
  }, [])
  useEffect(() => {
    setFilterTemplateList(templateList.filter(li => {
      if (searchText) {
        return li.title.indexOf(searchText) !== -1 && li.temp_sign_type === tempSignType
      }
      return li.temp_sign_type === tempSignType
    }))
  }, [searchText, tempSignType])
  useEffect(() => {
    dispatch(addScrollEvent({ name: 'fix-document-menu', handle: () => { fixHandle(setFixedMenuStyle) } }))
    return () => {
      dispatch(delScrollEvent('fix-document-menu'))
    }
  }, [])
  return (
    <div className={style.container}>
      <Model visible={visible} data={modifyTemplate} justyModifyFile={justyModifyFile} hide={() => { setVisible(false); setJustyModifyFile(false) }} refreshFn={() => {
        fnObj.refreshFn()
      }} />
      <div className={style['title-line']}>
        <span>{title}</span>
      </div>
      <div className={style.body}>
        <div className={style['left-block']} style={fixedMenuStyle}>
          <div className={style['menu-box']}>
            <div className={style['menu-search']}>
              <Input value={searchText} placeholder='请输入文书名称' onChange={e => setSearchText(e.target.value)} allowClear />
            </div>
            <div className={style['menu-types']}>
              <Select className={style.full} value={tempSignType} placeholder='请选择文书类型' onChange={v => setTempSignType(v)}>
                <Option value='location'>位置签名</Option>
                <Option value='keyword'>关键字签名</Option>
              </Select>
            </div>
            <div className={style['menu-list']}>
              <FreeScrollBar className='mock'>
                <List loading={loadingList} dataSource={filterTemplateList} renderItem={d => renderItem(d, currentTemplateid, (id) => {
                  setCurrentTemplateid(id)
                  setFile(null)
                  getTemplateById(id, setFile)
                })} />
              </FreeScrollBar>
            </div>
            <div className={style['menu-btn']}>
              <Button type='primary' block onClick={() => {
                setVisible(true)
                setModifyTemplate({ temp_sign_type: 'location' } as PDFTemplateSchema)
              }}>添加文书模板</Button>
            </div>
          </div>
        </div>
        <div className={style['right-block']}>
          <div className={style['btn-line']}>
            <Space>
              {renderBtns(currentTemplateid, templateIdMap, setJustyModifyFile, setModifyTemplate, setVisible, setCurrentTemplateid, setFile, () => {
                fnObj.refreshFn()
              })}
            </Space>
          </div>
          <div className={style['pdf-box']} ref={docBoxRef}>
            {renderPdf(ready, numPages, file, width, height, docBoxRef, setNumPages, setReady, setWidth, setHeight)}
          </div>
        </div>
      </div>
    </div>
  )
}

export default Main
